#ifndef HB_ASSISTLANDSYSTEM_H
#define HB_ASSISTLANDSYSTEM_H

#include <iostream>
#include <fstream>
#include <chrono>
#include <algorithm>
#include <unistd.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <string.h>
#include <map>
#include "application.hpp"
#include <dji_fc_subscription.h>
#include <dji_flight_controller.h>
#include <dji_positioning.h>
#include <dji_camera_image_handler.hpp>
#include <dji_liveview.h>
#include <dji_camera_stream_decoder.hpp>
#include <mutex>
#include <dji_gimbal_manager.h>
#include <dji_mop_channel.h>
#include <dji_platform.h>
#include <circular_buf.h>
#include <jsoncpp/json/json.h>
#include <link_protocol.h>
#include <dji_camera_manager.h>
#include <dji_perception.h>
#include <util_md5.h>
#include <util_misc.h>
#include <dji_waypoint_v2.h>



#define MOP_CHANNEL_FILE_SERVICE_CLIENT_MAX_SUPPORT_NUM     10
#define MOP_CHANNEL_FILE_SERVICE_RECV_BUFFER                (100 * 1024)
#define MOP_CHANNEL_FILE_SERVICE_SEND_BUFFER                (3 * 1024 * 1024)




enum OnBoardModeType{
	NoMode 			= 0,
	AssistLandMode 	= 1,
	AssistAvoidMode = 2
};


typedef enum {
    DJI_MOP_CHANNEL_FILE_TRANSFOR_CMD_REQUEST = 0x50,
    DJI_MOP_CHANNEL_FILE_TRANSFOR_CMD_ACK = 0x51,
    DJI_MOP_CHANNEL_FILE_TRANSFOR_CMD_RESULT = 0x52,
    DJI_MOP_CHANNEL_FILE_TRANSFOR_CMD_FILE_INFO = 0x60,
    DJI_MOP_CHANNEL_FILE_TRANSFOR_CMD_FILE_DOWNLOAD_REQ = 0x61,
    DJI_MOP_CHANNEL_FILE_TRANSFOR_CMD_FILE_DATA = 0x62,
    DJI_MOP_CHANNEL_FILE_TRANSFOR_CMD_STOP_REQUEST = 0x63,
    DJI_MOP_CHANNEL_FILE_TRANSFOR_CMD_STOP_ACK = 0x64,
} E_DjiMopChannel_FileTransforCmd;

typedef enum {
    DJI_MOP_CHANNEL_FILE_TRANSFOR_SUBCMD_REQUEST_UPLOAD = 0x00,
    DJI_MOP_CHANNEL_FILE_TRANSFOR_SUBCMD_REQUEST_DOWNLOAD = 0x01,
} E_DjiMopChannel_FileTransforRequestSubCmd;

typedef enum {
    DJI_MOP_CHANNEL_FILE_TRANSFOR_SUBCMD_ACK_OK = 0x00,
    DJI_MOP_CHANNEL_FILE_TRANSFOR_SUBCMD_ACK_REJECTED = 0x01,
} E_DjiMopChannel_FileTransforAckSubCmd;

typedef enum {
    DJI_MOP_CHANNEL_FILE_TRANSFOR_SUBCMD_RESULT_OK = 0x00,
    DJI_MOP_CHANNEL_FILE_TRANSFOR_SUBCMD_RESULT_FAILED = 0x01,
} E_DjiMopChannel_FileTransforResultSubCmd;

typedef enum {
    DJI_MOP_CHANNEL_FILE_TRANSFOR_SUBCMD_FILE_INFO_DEFAULT = 0xFF,
} E_DjiMopChannel_FileTransforFileInfoSubCmd;

typedef enum {
    DJI_MOP_CHANNEL_FILE_TRANSFOR_SUBCMD_DOWNLOAD_REQUEST = 0xFF,
} E_DjiMopChannel_FileTransforFileDownloadRequestSubCmd;

typedef enum {
    DJI_MOP_CHANNEL_FILE_TRANSFOR_SUBCMD_FILE_DATA_NORMAL = 0x00,
    DJI_MOP_CHANNEL_FILE_TRANSFOR_SUBCMD_FILE_DATA_END = 0x01,
} E_DjiMopChannel_FileTransforFileDataSubCmd;

typedef enum {
    DJI_MOP_CHANNEL_FILE_TRANSFOR_SUBCMD_STOP_UPLOAD = 0x00,
    DJI_MOP_CHANNEL_FILE_TRANSFOR_SUBCMD_STOP_DOWNLOAD = 0x01,
} E_DjiMopChannel_FileTransforStopSubCmd;



typedef enum {
    MOP_FILE_SERVICE_DOWNLOAD_IDEL = 0,
    MOP_FILE_SERVICE_DOWNLOAD_REQUEST_START,
    MOP_FILE_SERVICE_DOWNLOAD_FILE_INFO_SUCCESS,
    MOP_FILE_SERVICE_DOWNLOAD_FILE_INFO_FAILED,
    MOP_FILE_SERVICE_DOWNLOAD_DATA_SENDING,
    MOP_FILE_SERVICE_DOWNLOAD_FINISHED_SUCCESS,
    MOP_FILE_SERVICE_DOWNLOAD_FINISHED_FAILED,
    MOP_FILE_SERVICE_DOWNLOAD_STOP,
} E_MopFileServiceDownloadState;

typedef enum {
    MOP_FILE_SERVICE_UPLOAD_IDEL = 0,
    MOP_FILE_SERVICE_UPLOAD_REQUEST_START,
    MOP_FILE_SERVICE_UPLOAD_FILE_INFO_SUCCESS,
    MOP_FILE_SERVICE_UPLOAD_FILE_INFO_FAILED,
    MOP_FILE_SERVICE_UPLOAD_DATA_SENDING,
    MOP_FILE_SERVICE_UPLOAD_FINISHED_SUCCESS,
    MOP_FILE_SERVICE_UPLOAD_FINISHED_FAILED,
    MOP_FILE_SERVICE_UPLOAD_STOP,
} E_MopFileServiceUploadState;


typedef struct {
    uint8_t index;
    T_DjiTaskHandle clientRecvTask;
    T_DjiTaskHandle clientSendTask;
    T_DjiMopChannelHandle clientHandle;
    E_MopFileServiceDownloadState downloadState;
	char fileName[32];
    uint16_t downloadSeqNum;
    E_MopFileServiceUploadState uploadState;
    uint16_t uploadSeqNum;
} T_MopFileServiceClientContent;

typedef struct {
    bool isExist;
    uint32_t fileLength;
    char fileName[32];
    uint8_t md5Buf[16];
} T_DjiMopChannel_FileInfo;

typedef struct {
    char fileName[32];
} T_DjiMopChannel_DwonloadReq;

typedef struct {
    uint8_t cmd;
    uint8_t subcmd;
    uint16_t seqNum;
    uint32_t dataLen;
    union dataType {
        T_DjiMopChannel_FileInfo fileInfo;
        T_DjiMopChannel_DwonloadReq dwonloadReq;
        uint8_t fileData[0];
    } data;
} T_DjiMopChannel_FileTransfor;


class djiFlightHandler
{
public:
	djiFlightHandler();
	~djiFlightHandler();
	
	bool startUpSystem();

	void sleepMs(uint32_t timeMs);

	void getCurrentTimeMs(uint32_t &timeMs);

	//subscription message
	bool subscriptionInit();

	bool subscriptionFlightMode();

	bool subscriptionFlightStatus();

	bool subscriptionFlightVelocity();

	bool subscriptionFlightPosition();

	bool subscriptionFlightRelativeHeight();

	bool subscriptionRtkConnectStatus();

	bool subscriptionRtkPositionInfo();

	bool subscriptionRtkYawInfo();

	bool subscriptionFlightQuaternion();

	bool subscriptionRtkPosition();

	bool subscriptionGpsDetail();

	bool subscriptionHeightFusion();

	bool subscriptionGimbalAngles();

	bool subscriptionGimbalStatus();

	bool subscriptionGimbalControlMOde();

	bool subscriptionAltitudeFused();

	bool subscriptionAltitudeBarometer();

	bool subscriptionAltitudeHomePoint();

	bool subscriptionWholeBatteryInfo();

	bool subscriptionAvoidData();

	//liveView relation
	bool startDjiLiveView();

	void stopDjiLiveView();

	bool startFpvCameraStream(enum OnBoardModeType mode, CameraImageCallback callback, void *userData, E_DjiLiveViewCameraSource source = DJI_LIVEVIEW_CAMERA_SOURCE_DEFAULT);

    bool stopFpvCameraStream(enum OnBoardModeType mode, E_DjiLiveViewCameraSource source = DJI_LIVEVIEW_CAMERA_SOURCE_DEFAULT);

    bool startMainCameraStream(enum OnBoardModeType mode, CameraImageCallback callback, void *userData, E_DjiLiveViewCameraSource source = DJI_LIVEVIEW_CAMERA_SOURCE_DEFAULT);

    bool stopMainCameraStream(enum OnBoardModeType mode , E_DjiLiveViewCameraSource source = DJI_LIVEVIEW_CAMERA_SOURCE_DEFAULT);

    bool startViceCameraStream(enum OnBoardModeType mode, CameraImageCallback callback, void *userData, E_DjiLiveViewCameraSource source = DJI_LIVEVIEW_CAMERA_SOURCE_DEFAULT);

    bool stopViceCameraStream(enum OnBoardModeType mode, E_DjiLiveViewCameraSource source = DJI_LIVEVIEW_CAMERA_SOURCE_DEFAULT);

    bool startTopCameraStream(enum OnBoardModeType mode, CameraImageCallback callback, void *userData, E_DjiLiveViewCameraSource source = DJI_LIVEVIEW_CAMERA_SOURCE_DEFAULT);

    bool stopTopCameraStream(enum OnBoardModeType mode, E_DjiLiveViewCameraSource source = DJI_LIVEVIEW_CAMERA_SOURCE_DEFAULT);

	//Subscribe the raw images of both stereo cameras
	bool getStereoCameraParameters(T_DjiPerceptionCameraParametersPacket &packet);

	bool subscribePerceptionImage(E_DjiPerceptionDirection direction, DjiPerceptionImageCallback callback);

	bool unsubscribePerceptionImage(E_DjiPerceptionDirection direction);

	//gimbal manager
	bool gimbalManagerSetMode(E_DjiMountPosition mountPosition, E_DjiGimbalMode mode);

	bool gimbalManagerReset(E_DjiMountPosition mountPosition);

	bool gimbalManagerSetModeAndReset(E_DjiMountPosition mountPosition, E_DjiGimbalMode mode, E_DjiGimbalResetMode resetMode = DJI_GIMBAL_RESET_MODE_YAW);

	bool gimbalManagerRotate(E_DjiMountPosition mountPosition, T_DjiGimbalManagerRotation rotation);

	bool gimbalManagerSetModeAndRestAndRotate(E_DjiMountPosition mountPosition, E_DjiGimbalMode mode, T_DjiGimbalManagerRotation rotation);

	bool gimbalManagersetModeAndRotate(E_DjiMountPosition mountPosition, E_DjiGimbalMode mode, T_DjiGimbalManagerRotation rotation);

	//set camera zoom
	bool setCameraZoom(E_DjiMountPosition mountPosition, float multiplier);

	//get laser ranging info
	bool getLaserRangingInfo(E_DjiMountPosition position, float &distance);

	//get camera type
	bool getCameraType(E_DjiMountPosition position, E_DjiCameraType &cameraType);

	void getCameraType();

	bool isDoubleGimbal();

	//switch H30 or H30T stream source
	bool switchH30XStreamSource(E_DjiMountPosition position, E_DjiCameraManagerStreamSource streamSource);

	//flight mode  handle
	void setFlightMode(T_DjiFcSubscriptionDisplaymode *mode, const T_DjiDataTimestamp *timestamp);

	void getFlightMode(T_DjiFcSubscriptionDisplaymode &mode, T_DjiDataTimestamp &timestamp);

	//flight status handle
	void setFlightStatus(T_DjiFcSubscriptionFlightStatus *status, const T_DjiDataTimestamp *timestamp);

	void getFlightStatus(T_DjiFcSubscriptionFlightStatus & status, T_DjiDataTimestamp &timestamp);

	//flight veloctiy handle
	void setFlightVelocity(T_DjiFcSubscriptionVelocity *velocity, const T_DjiDataTimestamp *timestamp);

	void getFlightVelocity(T_DjiFcSubscriptionVelocity &velocity, T_DjiDataTimestamp &timestamp);


	//flight position handle
	void setFlightPosition(T_DjiFcSubscriptionPositionFused *position, const T_DjiDataTimestamp *timestamp);

	void getFlightPosition(T_DjiFcSubscriptionPositionFused &position, T_DjiDataTimestamp &timestamp);


	//flight  relative height handle
	void setFlightRelativeHeight(T_DjiFcSubscriptionHeightRelative *height, const T_DjiDataTimestamp *timestamp);

	void getFlightRelativeHeight(T_DjiFcSubscriptionHeightRelative &height, T_DjiDataTimestamp &timestamp);

	//flight rtk connect status handle
	void setRtkConnectStatus(T_DjiFcSubscriptionRTKConnectStatus *status, const T_DjiDataTimestamp *timestamp);

	void getRtkConnectStatus(T_DjiFcSubscriptionRTKConnectStatus &status, T_DjiDataTimestamp &timestamp);


	//flight rtk position information handle
	void setRtkPositionInfo(T_DjiFcSubscriptionRtkPositionInfo *status, const T_DjiDataTimestamp *timestamp);

	void getRtkPositionInfo(T_DjiFcSubscriptionRtkPositionInfo &status, T_DjiDataTimestamp &timestamp);

	//flight rtk yaw information handle
	void setRtkYawInfo(T_DjiFcSubscriptionRtkYawInfo *status, const T_DjiDataTimestamp *timestamp);

	void getRtkYawInfo(T_DjiFcSubscriptionRtkYawInfo &status, T_DjiDataTimestamp &timestamp);


	//flight Quat
	void setFlightQuat(T_DjiFcSubscriptionQuaternion *quat, const T_DjiDataTimestamp *timestamp);

	void getFlightQuat(T_DjiFcSubscriptionQuaternion &quat, T_DjiDataTimestamp &timestamp);

	//rtk position
	void setRtkPosition(T_DjiFcSubscriptionRtkPosition * position, const T_DjiDataTimestamp *timestamp);

	void getRtkPosition(T_DjiFcSubscriptionRtkPosition &position, T_DjiDataTimestamp &timestamp);


	//gps details
	void setGpsDetails(T_DjiFcSubscriptionGpsDetails *gpsStatus, const T_DjiDataTimestamp *timestamp);

	void getGpsDetails(T_DjiFcSubscriptionGpsDetails &gpsStatus, T_DjiDataTimestamp &timestamp);


	//height fusion
	void setHeightFusion(T_DjiFcSubscriptionHeightFusion *height, const T_DjiDataTimestamp *timestamp);

	void getHeightFusion(T_DjiFcSubscriptionHeightFusion &height, T_DjiDataTimestamp &timestamp);

	//gimbal angles
	void setGimbalAngles(T_DjiFcSubscriptionGimbalAngles *pry, const T_DjiDataTimestamp *timestamp);

	void getGimbalAngles(T_DjiFcSubscriptionGimbalAngles &pry, T_DjiDataTimestamp &timestamp);

	//gimbal status
	void setGimbalStatus(T_DjiFcSubscriptionGimbalStatus *status, const T_DjiDataTimestamp *timestamp);

	void getGimbalStatus(T_DjiFcSubscriptionGimbalStatus &status, T_DjiDataTimestamp &timestamp);

	//gimbal control mode
	void setGimbalControlMode(T_DjiFcSubscriptionGimbalControlMode *mode, const T_DjiDataTimestamp *timestamp);

	void getGimbalControlMode(T_DjiFcSubscriptionGimbalControlMode &mode, T_DjiDataTimestamp &timestamp);

	//altitude fused
	void setAltitudeFused(T_DjiFcSubscriptionAltitudeFused *alt, const T_DjiDataTimestamp *timestamp);

	void getAltitudeFused(T_DjiFcSubscriptionAltitudeFused &alt, T_DjiDataTimestamp &timestamp);

	//altitude barometer
	void setAltitudeBarometer(T_DjiFcSubscriptionAltitudeBarometer *alt, const T_DjiDataTimestamp *timestamp);

	void getAltitudeBarometer(T_DjiFcSubscriptionAltitudeBarometer &alt, T_DjiDataTimestamp &timestamp);

	//altitude homePoint
	void setAltitudeHomePoint(T_DjiFcSubscriptionAltitudeOfHomePoint *alt, const T_DjiDataTimestamp *timestamp);

	void getAltitudeHomePoint(T_DjiFcSubscriptionAltitudeOfHomePoint &alt, T_DjiDataTimestamp &timestamp);

	//battery info
	void setBatteryInfo(T_DjiFcSubscriptionWholeBatteryInfo *batteryInfo, const T_DjiDataTimestamp *timestamp);

	void getBatteryInfo(T_DjiFcSubscriptionWholeBatteryInfo &batteryInfo, T_DjiDataTimestamp &timestamp);

	//avoid data
	void setAvoidData(T_DjiFcSubscriptionAvoidData *avoidData, const T_DjiDataTimestamp *timestamp);

	void getAvoidData(T_DjiFcSubscriptionAvoidData &avoidData, T_DjiDataTimestamp &timestamp);


	void getRollPitchYawFromQuaternion(T_DjiFcSubscriptionQuaternion &quat, double &roll, double &pitch, double &yaw);
	double wrap360(const double angle);

	double getCurrentYaw();


	//flight control

	//get control authority
	bool obtainJoyStickCtrlAuthority(enum OnBoardModeType mode);

	//quit control authority
	bool releaseJoyStickCtrlAuthority(enum OnBoardModeType mode);

	//control copter take off
	bool sendTakeOffCommandToCopter(enum OnBoardModeType mode);

	//control copter auto land
	bool sendAutoLandCommandToCopter(enum OnBoardModeType mode);

	//control copter auto land no ground action
	bool sendAutoConfirmLandCommandToCopter(enum OnBoardModeType mode);

	bool sendAutoForceLandCommandToCopter(enum OnBoardModeType mode);

	bool sendLandPointToCopter(enum OnBoardModeType mode, T_DjiFlightControllerHomeLocation homeLocation);

	bool sendStartGoHomeToCopter(enum OnBoardModeType mode);

	//cancel land
	bool sendCancelLandCommandtoCopter(enum OnBoardModeType mode);

	//control copter yaw
	bool sendYawControlToCopter(enum OnBoardModeType mode, double angle);

	//set control mode
	bool setFlightControlModeByVelocity(enum OnBoardModeType mode);

	double getTargetYawAngle();

	bool getYawControlFunctionFlag();

	void setYawControlFunctionFlag( bool flag);

	//control copter velocity, 

	//x is  north velocity, y is east velocity,flight rotation not affects the flight velocity bearing.
	bool sendVelocityControlToCopter(enum OnBoardModeType mode, T_DjiVector3f velocity, uint32_t timeoutMs, double yawRate = 0);

	bool velocityControlToCopter(enum OnBoardModeType mode, T_DjiVector3f velocity, double yawRate = 0);

	//gie a horizontal velocity size and bearing to control flight move in the horizontal plane
	bool sendHorizontalVelocitySizeAndBearingControlToCopter(enum OnBoardModeType mode, float velocitySize, double velocityBearing, uint32_t timeoutMs);

	bool controlCopterTurnOffMotors(enum OnBoardModeType mode);


	bool getVelocityControlFunctionFlag();

	void setVelocityControlFunctionFlag(bool flag);

	uint32_t getVelocityControlTimeoutMs();

	
	void getVelocityControlVelocity(T_DjiVector3f &velocity);

	void getVelocitycontrolYawRate(double &yawRate);

	//control copter position
	bool sendPositionControlToCopter(enum OnBoardModeType mode, T_DjiVector3f position, uint32_t timeoutMs);

	bool sendPositioncontrolToCopter(enum OnBoardModeType mode, T_DjiPositioningPosition position);

	bool getPositionControlFunctionFlag();

	void setPositionControlFunctionFlag(bool flag);

	uint32_t getPositionControlTimeoutMs();

	void getPositionControlPosition(T_DjiVector3f &position);

	enum OnBoardModeType getObtainJoyStickCtrlAuthorityFlag();

	//communicate with msdk by mop channel
	bool mopChannelStartService();

	bool getMopChannelSendNormalTaskRunFlag();

	void setMopChannelSendNormalTaskRunFlag(bool flag);

	bool getMopChannelRecvNormalTaskRunFlag();

	void setMopChannelRecvNormalTaskRunFlag(bool flag);

	void writeMopChannelRecvNormalBuffer(unsigned char *pdata, unsigned int count);

	void writeMopChannelSendNormalBuffer(unsigned char *pdata, unsigned int count);

	unsigned int readMopChannelRecvNormalBuffer(unsigned char *pdata, unsigned int len);

	unsigned int readMopChannelSendNormalBuffer(unsigned char *pdata, unsigned int len);

	void clearMopChannelSendNormalBuffer();

	void clearMopChannelRecvNormalBuffer();

	unsigned int getFreeCountMopChannelSendNormalBuffer();

	unsigned int getFreeCountMopChannelRecvNormalBuffer();

	unsigned int getDataCountMopChannelSendNormalBuffer();
	
	unsigned int getDataCountMopChannelRecvNormalBuffer();

	bool semaphoreCreate(uint32_t initValue, T_DjiSemaHandle *semaphore);

	bool semaphorePost();

	bool semaphoreWait();

	bool mopChannelCreate();

	bool mopChannelBind();

	bool mopChannelAccept();

	bool mopChannelRecvData(uint8_t *data, uint32_t len, uint32_t *realLen);

	bool mopChannelSendData(uint8_t *data, uint32_t len, uint32_t *realLen);

	//file mop communication
	bool fileMopChannelCreate();

	bool fileMopChannelBind();

	bool fileMopChannelAcceptHandle();

	bool fileMopChannelRecvData(uint8_t clientNum, uint8_t *data, uint32_t len, uint32_t *realLen);

	bool fileMopChannelSendData(uint8_t clientNum, uint8_t *data, uint32_t len, uint32_t *realLen);

	bool getMopChannelConnectedFlag();

	void setMopChannelConnectedFlag(bool flag);

	bool getFlileMopChannelConnectedFlag();

	void setFileMopChannelConnectedFlag(bool flag);

	T_MopFileServiceClientContent &getFileServiceContentHandler(uint8_t clientNum);

	
	typedef void (*mopChannelRecvCallback)(linkProtocolType msg);

	bool registerMopChannelRecvCallback(mopChannelRecvCallback function, enum OnBoardModeType mode);

	void mopCommunicationWithMsdkRun();

	void setAssistLandSystemStatus(enum assistLandSystemState status);

	void setAssistAvoidSystemStatus(enum assistAvoidSystemState status);

	int packageMessage(uint8_t *buf, uint8_t msgId,std::string msgData, uint16_t msgLen);

	//send msg to msdk
	void sendHeartBeatToMsdk();

	void sendCancelLandToMsdk();

	//get msg from msdk
	void getHeartBeatFromMsdk(linkProtocolType &msg);

	bool getIsFixBaseRTKStaus();

	//log
	bool getLogDir();

	bool createLogFile();

	bool writeLogFile(const char * format, ...);

	bool clearAllLogFile();

	bool viewLogFile(vector<string> &logFileName);

	void recodeCpuTemperature();

	//download log
	//handle all types of log download requests from the msdk
	void handleLogMessage(linkProtocolType &msg);

	//handle all types of log download requests from the msdk
	void handleLogRequestList(linkProtocolType &msg);

	//handle request for log data
	void handleLogRequestData(linkProtocolType &msg);

	//handle request to erase log data
	void handleLogRequestErase(linkProtocolType &msg);

	//handle request to stop transfer and resume normal logging
	void handleLogRequestEnd(linkProtocolType &msg);

	bool openReadFile(uint32_t logNum);

	void closeReadFile();

	int32_t readLogData(char *buffer, int readSize);

	bool getLogFileSize(uint32_t logNum, uint32_t &FileSize);

	//trigger sending of log messages if there are some pending
	bool handleLogSend();

	//trigger sending of log messages if there are some pending
	bool handleLogSendListing();

	//trigger sending of log data if there are some pending
	bool handleLogSendData();

	//handle update firware msg
	void handleUpdateFirwareMessage(linkProtocolType &msg);

	void handleUpdateFirware(linkProtocolType &msg);

	void handleUpdateFirwareData(linkProtocolType &msg);

	void sendUpdateFirwareState(enum updataFirwareState state);

	void setLandPoint(linkProtocolType &msg);

	bool getLandPoint(double &latitude, double &longitude);

	void sendAckMessage(enum linkProtocolMessageId, enum ackMsgState status);

	bool getCanLandFlag();

	int getNoHeartCount();

	void noHeartCountSelfAdd();

	//waypoint control
	bool startWayPoint();

	bool stopWayPoint();

	bool pauseWayPoint();

	bool resumeWayPoint();

	E_DjiCameraType GetCurrentCameraType();

private:
	T_DjiOsalHandler *m_osalHandler;

	T_DjiReturnCode m_returnCode;

	//liveView ralate
	bool m_startDjiLiveViewFlag;
	enum OnBoardModeType m_startFpvCameraStreamBoardModeFlag;
	enum OnBoardModeType m_startMainCameraStreamBoardModeFlag;
	enum OnBoardModeType m_startViceCameraStreamBoardModeFlag;
	enum OnBoardModeType m_startTopCameraStreamBoardModeFlag;

	//fligth mode relate
	T_DjiFcSubscriptionDisplaymode m_flightMode;
	T_DjiDataTimestamp m_flightModeUpdateTime;
	std::mutex m_flightModeLock;
	

	//fligth status relate
	T_DjiFcSubscriptionFlightStatus m_flightStatus;
	T_DjiDataTimestamp m_flightStatusUpdateTime;
	std::mutex m_flightStatusLock;

	//fligth velocity relate
	T_DjiFcSubscriptionVelocity m_flightVelocity;
	T_DjiDataTimestamp m_flightVelocityUpdateTime;
	std::mutex m_flightVelocityLock;

	//fligth position relate
	T_DjiFcSubscriptionPositionFused m_flightPosition;
	T_DjiDataTimestamp m_flightPositionUpdateTime;
	std::mutex m_flightPositionLock;

	//fligth relative height
	T_DjiFcSubscriptionHeightRelative m_relativeHeight;
	T_DjiDataTimestamp m_flightRelativeHeightUpdateTime;
	std::mutex m_relativeHeightLock;

	//flight rtk connect status
	T_DjiFcSubscriptionRTKConnectStatus m_rtkConnectStatus;
	T_DjiDataTimestamp m_rtkConnectStatusUpdateTime;
	std::mutex m_rtkConnectStatusLock;

	//flight rtk position info
	T_DjiFcSubscriptionRtkPositionInfo m_rtkPositionInfo;
	T_DjiDataTimestamp m_rtkPoistionInfoUpdateTime;
	std::mutex m_rtkPositionInfoLock;

	//flight rkt yaw info
	T_DjiFcSubscriptionRtkYawInfo m_rtkYawInfo;
	T_DjiDataTimestamp m_rtkYawInfoUpdateTime;
	std::mutex m_rtkYawInfoLock;

	//flight Quat
	T_DjiFcSubscriptionQuaternion m_FlightQuat;
	T_DjiDataTimestamp m_FlightQuatUpdateTime;
	std::mutex m_FlightQuatLock;

	//rtk position
	T_DjiFcSubscriptionRtkPosition m_rtkPosition;
	T_DjiDataTimestamp m_rtkPostionUpdateTime;
	std::mutex m_rtkPositionLock;

	//gps details
	T_DjiFcSubscriptionGpsDetails m_gpsDetails;
	T_DjiDataTimestamp m_gpsDetailsUpdateTime;
	std::mutex m_gpsDetailsLock;

	//height fusion
	T_DjiFcSubscriptionHeightFusion m_heightFusion;
	T_DjiDataTimestamp m_heightFusionUpdateTime;
	std::mutex m_heightFusionLock;

	//gimbal angles
	T_DjiFcSubscriptionGimbalAngles m_gimbalAnglesPry;
	T_DjiDataTimestamp m_gimbalAnglesUpdateTime;
	std::mutex m_gimbalAnglesPryLock;

	//gimbal status
	T_DjiFcSubscriptionGimbalStatus m_gimbalStatus;
	T_DjiDataTimestamp m_gimbalStatusUpdateTime;
	std::mutex m_gimbalStatusLock;

	//gimbal control mode
	T_DjiFcSubscriptionGimbalControlMode m_gimbalControlMode;
	T_DjiDataTimestamp m_gimbalControlModeUpdateTime;
	std::mutex m_gimbalControlModeLock;

	//altitude fused
	T_DjiFcSubscriptionAltitudeFused m_altitudeFused;
	T_DjiDataTimestamp m_altitudeFusedUpdateTime;
	std::mutex m_altitudeFusedLock;

	//altitude barometer
	T_DjiFcSubscriptionAltitudeBarometer m_altitudeBarometer;
	T_DjiDataTimestamp m_altitudeBarometerUpdateTime;
	std::mutex m_altitudeBarometerLock;

	//altitude homePoint
	T_DjiFcSubscriptionAltitudeOfHomePoint m_altitudeHomePoint;
	T_DjiDataTimestamp m_altitudeHomePointUpdateTime;
	std::mutex m_altitudeHomePointLock;

	//battery info
	T_DjiFcSubscriptionWholeBatteryInfo m_batteryInfo;
	T_DjiDataTimestamp m_batteryInfoUpdateTime;
	std::mutex m_batteryInfoLock;

	//avoid data
	T_DjiFcSubscriptionAvoidData m_avoidData;
	T_DjiDataTimestamp m_avoidDataUpdateTime;
	std::mutex m_avoidDataLock;

	bool m_subscriptionFlag;
	bool m_getLogDirFlag;

	//flight control
	enum OnBoardModeType m_obtainJoyStickCtrlAuthorityFlag;
	
	//angle control
	double m_targetAngle;
	pthread_t m_yawControlTid;
	bool m_yawControlFunctionFlag;

	//velocity control
	pthread_t m_velocityControlTid;
	bool m_velocityControlFunctionFlag;
	T_DjiVector3f m_velocityControlVelocity;
	double m_velocitycontrolYawrate;
	uint32_t m_velocityControlTimeoutMs;

	//position control
	pthread_t m_positionControlTid;
	bool m_positionControlFunctionFlag;
	T_DjiVector3f m_positionControlPosition;
	uint32_t m_positionControlTimeoutMs;

	//mop channel buff
	struct circularBuffer m_mopChannelSendBuffer;
	struct circularBuffer m_mopChannelRecvBuffer;
	bool m_mopChannelStartServiceFlag;
	bool m_mopChannelSendNormalTaskRunFlag;
	bool m_mopChannelRecvNormalTaskRunFlag;
	bool m_mopChannelConnectedFlag;

	T_DjiMopChannelHandle m_mopChannelRecvNormalHandle;
	T_DjiMopChannelHandle m_mopChannelNormalOutHandle;

	T_DjiSemaHandle m_mopChannelReadySema;
	T_DjiTaskHandle m_mopChannelNormalSendTask;
	T_DjiTaskHandle m_mopChannelNormalRecvTask;

	//mop file communication
	T_DjiTaskHandle m_fileServiceMopChannelAcceptTask;
	T_DjiMopChannelHandle m_fileServiceMopChannelHandle;
	T_MopFileServiceClientContent m_fileServiceContent[MOP_CHANNEL_FILE_SERVICE_CLIENT_MAX_SUPPORT_NUM];
	bool m_flileMopChannelConnectedFlag;

	//callback
	vector<mopChannelRecvCallback> m_mopChannelRecvCallBackFunction;
	vector<enum OnBoardModeType> m_mopChannelRecvCallBackModeType;


	enum assistLandSystemState m_assistLandSystemStatus;
	enum assistAvoidSystemState m_assistAvoidSystemStatus;

	//update firware
	FILE* m_updateFp;
	bool m_updateFlag;
	int m_updateDataSize;
	int m_updateOffsetCount;
	string md5crc;

	//land point
	bool m_landPointOk;
	bool m_canLandFlag;
	int m_noHeartCount;
	double m_LandPointLatitude;
	double m_LandPointLongitude;
	bool m_isTestMode;
	bool m_isFixBaseRTK;

	E_DjiCameraType m_cameraType;
	E_DjiCameraType m_cameraType2;


	//log file
	FILE *m_logFp;
	int m_quatLogCount;
	int m_gimbalAnglesLogCount;
	int m_velocityLogCount;
	int m_avoidDataLogCount;
	uint32_t m_lastLogNum;

	//log download
	bool m_logListing; //sending log list
	bool m_logSending; //sending log data
	bool m_logSendingFlag;
	bool m_openReadFileFlag;
	uint32_t m_logDataSize; //size of log file
	uint32_t m_logNumData; //log number for data send
	uint32_t m_logDataOffset;
	uint16_t m_logNextListEntry; //next log list entry to send
	uint16_t m_logLastListEntry; //last log list entry to send
	uint16_t m_logNumLogs;
	FILE *m_readFd;
};


extern djiFlightHandler flightHandler;

#endif  //HB_ASSISTLANDSYSTEM_H

